Slient Blog

RxJava RxBinding基础

2017-03-11

RxBinding是什么

把 Android 中各种 UI 控件的事件转换为 RxJava 中的数据流。这样就可以把 UI 控件的事件当做 RxJava 中的数据流来使用了。 比如 View 的 onClick 事件,使用 RxView.clicks(view) 即可获取到一个 Observable 对象,每当用户点击这个 View 的时候,该 Observable 对象就发射一个事件(onNext 被调用), Observable 的 Observer 订阅者就可以通过 onNext 回调知道用户点击了 View。

开源项目

RxBinding 地址:https://github.com/JakeWharton/RxBinding

添加依赖

1
2
3
4
5
6
/ RxBinding
compile 'com.jakewharton.rxbinding:rxbinding:0.3.0'
compile 'com.jakewharton.rxbinding:rxbinding-support-v4:0.3.0'
compile 'com.jakewharton.rxbinding:rxbinding-appcompat-v7:0.3.0'
compile 'com.jakewharton.rxbinding:rxbinding-design:0.3.0'
compile 'com.jakewharton.rxbinding:rxbinding-recyclerview-v7:0.3.0'

简单使用

button点击事件

1
2
3
4
5
6
7
8
Button b = (Button)findViewById(R.id.button);
Subscription buttonSub =
RxView.clicks(b).subscribe(new Action1<Void>() {
@Override
public void call(Void aVoid) {
// do some work here
}
});

EditText添加文本改变事件

1
2
3
4
5
6
7
8
9
final EditText name = (EditText) v.findViewById(R.id.name);
Subscription editTextSub =
RxTextView.textChanges(name)
.subscribe(new Action1<String>() {
@Override
public void call(String value) {
// do some work with the updated text
}
});

看到这里你可能会说,这个没什么太大的变化呀,也没有什么太优势的地方。大佬别着急。

RxBinding最好的运用场景是在定时操作,循环操作。还有对重复点击事件的处理上

设置Button防止抖动

1
2
3
4
5
6
7
RxView.clicks(button).throttleFirst(2, TimeUnit.SECONDS).subscribe(new Action1<Void>() {
@Override
public void call(Void aVoid) {
//两秒钟之内只取一个点击事件,防抖操作
// do some work with the updated text
}
});

考虑在搜索框中输入相应的内容,当内容的长度至少三个字符长度的时候开始触发响应事件(设置100ms延迟),使用RxJava实现(debounce()在一定的时间内没有操作就会发送事件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
RxTextView.textChanges(searchTextView)
.filter(new Func1<String, Boolean> (){
@Override
public Boolean call(String s) {
return s.length() > 2;
}
})
.debounce(100, TimeUnit.MILLISECONDS)
.switchMap(new Func1<String, Observable<List<Result>>>() {
makeApiCall(s);
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(/* attach observer */);

CheckBox相关的操作

在用户登录界面时,如果用户未勾选同意用户协议,不允许登录

1
2
3
4
5
6
7
8
RxCompoundButton.checkedChanges(checkBox2)
.subscribe(new Action1<Boolean>() {
@Override
public void call(Boolean aBoolean) {
btn_login.setClickable(aBoolean);
btn_login.setBackgroundResource(aBoolean ? R.color.can_login : R.color.not_login);
}
});

监听RecyclerView的滚动事件以及数据更改事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
RxRecyclerView.scrollStateChanges(mRxBindingRecycler)
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
Log.d("TAG", "change");
}
});
RxRecyclerViewAdapter.dataChanges(mAdapter)
.subscribe(new Action1<MyAdapter>() {
@Override
public void call(MyAdapter myAdapter) {
Log.e("TAG", "DATA CHANGED");
}
});
mAdapter.notifyDataSetChanged();

因为RxRecyclerView和RecyclerView一样并没有提供直接的item点击事件,所以参考以前RecyclerView写了一个点击事件这里用到了RxBus处理数据的传递,我们并没有在RecyclerView内部直接去处理事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View view = LayoutInflater.from(mContext).inflate(R.layout.binding_item, null);
final ViewHolder viewHolder = new ViewHolder(view);
RxView.clicks(view)
.subscribe(new Action1<Void>() {
@Override
public void call(Void aVoid) {
RxBus.getInstance().send(new UserBean("",viewHolder.getAdapterPosition()+""));
Log.i("TGA",viewHolder.getAdapterPosition()+"");
}
});
return viewHolder;
}

在我们处理数据的地方获取该事件

1
2
3
4
5
6
7
8
9
RxBus.getInstance()
.toObserverable(UserBean.class)
.subscribe(new Action1<UserBean>() {
@Override
public void call(UserBean userBean) {
// TODO: 2017/3/13
}
});

当然上面的只是一些简单的案例,具体的内容请观看大神的RxBinding

Tags: Android
使用微信添加

若你觉得我的文章对你有帮助,请添加我为好友

扫描二维码,分享此文章